/**
 * Copyright &copy; 2013-2015 山东易科德软件有限公司 All rights reserved.
 */
package cn.net.ecode.common.persistence.interceptor;

import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.plugin.Interceptor;

import com.google.common.collect.Maps;

import cn.net.ecode.common.config.Global;
import cn.net.ecode.common.persistence.Page;
import cn.net.ecode.common.persistence.dialect.Dialect;
import cn.net.ecode.common.persistence.dialect.db.DB2Dialect;
import cn.net.ecode.common.persistence.dialect.db.DerbyDialect;
import cn.net.ecode.common.persistence.dialect.db.H2Dialect;
import cn.net.ecode.common.persistence.dialect.db.HSQLDialect;
import cn.net.ecode.common.persistence.dialect.db.MySQLDialect;
import cn.net.ecode.common.persistence.dialect.db.OracleDialect;
import cn.net.ecode.common.persistence.dialect.db.PostgreSQLDialect;
import cn.net.ecode.common.persistence.dialect.db.SQLServer2005Dialect;
import cn.net.ecode.common.persistence.dialect.db.SybaseDialect;
import cn.net.ecode.common.utils.Reflections;

import java.io.Serializable;
import java.util.Map;
import java.util.Properties;

/**
 * Mybatis拦截器基类
 * @author ThinkGem
 * @version 2015-1-14
 */
public abstract class BaseInterceptor implements Interceptor, Serializable {

	private static final long serialVersionUID = 1L;
	
	protected Log log = LogFactory.getLog(this.getClass());

	protected static final String PAGE = "page";

	protected static final String DELEGATE = "delegate";

	protected static final String MAPPED_STATEMENT = "mappedStatement";
	
	protected static final Map<String, Dialect> dialectMap = Maps.newHashMap();

	/**
	 * 对参数进行转换和检查
	 * @param parameterObject 参数对象
	 * @param page            分页对象
	 * @return 分页对象
	 * @throws NoSuchFieldException 无法找到参数
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected static Page<Object> convertParameter(Object parameterObject, Page<Object> page) {
		try {
			if (parameterObject instanceof Page) {
				return (Page<Object>) parameterObject;
			} else if (parameterObject instanceof Map) {
				return (Page<Object>) ((Map) parameterObject).get(PAGE);
			} else {
				return (Page<Object>) Reflections.getFieldValue(parameterObject, PAGE);
			}
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 初始化属性
	 * @param p
	 */
	protected void initProperties(Properties p) {
		
	}
	
	/**
	 * 获取自定义方言，数据库类型，插件支持的数据库
	 */
	public static Dialect getDialect() {
		String jdbcType = Global.getJdbcType();
		Dialect dialect = dialectMap.get(jdbcType);
		if (dialect == null){
			if ("db2".equals(jdbcType)) {
				dialect = new DB2Dialect();
			} else if ("derby".equals(jdbcType)) {
				dialect = new DerbyDialect();
			} else if ("h2".equals(jdbcType)) {
				dialect = new H2Dialect();
			} else if ("hsql".equals(jdbcType)) {
				dialect = new HSQLDialect();
			} else if ("mysql".equals(jdbcType)) {
				dialect = new MySQLDialect();
			} else if ("oracle".equals(jdbcType)) {
				dialect = new OracleDialect();
			} else if ("postgre".equals(jdbcType) || "highgo".equals(jdbcType)) {
				dialect = new PostgreSQLDialect();
			} else if ("mssql".equals(jdbcType) || "sqlserver".equals(jdbcType)) {
				dialect = new SQLServer2005Dialect();
			} else if ("sybase".equals(jdbcType)) {
				dialect = new SybaseDialect();
			}
			dialectMap.put(jdbcType, dialect);
		}
		if (dialect == null) {
			throw new RuntimeException("mybatis dialect error.");
		}
		return dialect;
	}
	
}
